package com.study.javaFx.view;

import com.study.javaFx.model.Machine;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.fasterxml.jackson.databind.ObjectMapper;

public class MachineView {

    private final HttpClient httpClient = HttpClient.newHttpClient();
    private final ObjectMapper objectMapper = new ObjectMapper().setPropertyNamingStrategy(com.fasterxml.jackson.databind.PropertyNamingStrategies.SNAKE_CASE);
    private final String BASE_URL = "http://localhost:8080/api/machine";

    /**
     * 弹窗方式显示查询机器界面
     */
    public void showQueryDialog() {
        Stage dialog = new Stage();
        dialog.setTitle("查询机器");
        dialog.initModality(javafx.stage.Modality.APPLICATION_MODAL);

        TableView<Machine> table = new TableView<>();
        table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
        TableColumn<Machine, Number> idCol = new TableColumn<>("机器ID");
        idCol.setCellValueFactory(cellData -> cellData.getValue().machineIdProperty());
        TableColumn<Machine, Number> labIdCol = new TableColumn<>("机房ID");
        labIdCol.setCellValueFactory(cellData -> cellData.getValue().labIdProperty());
        TableColumn<Machine, Number> typeIdCol = new TableColumn<>("机型ID");
        typeIdCol.setCellValueFactory(cellData -> cellData.getValue().typeIdProperty());
        TableColumn<Machine, String> statusCol = new TableColumn<>("状态");
        statusCol.setCellValueFactory(cellData -> cellData.getValue().statusProperty());
        table.getColumns().addAll(idCol, labIdCol, typeIdCol, statusCol);

        // 查询面板
        GridPane queryPane = new GridPane();
        queryPane.setPadding(new Insets(10));
        queryPane.setHgap(10);
        queryPane.setVgap(10);
        queryPane.add(new Label("输入机器ID:"), 0, 0);
        TextField idField = new TextField();
        queryPane.add(idField, 1, 0);
        Button queryBtn = new Button("查询");
        queryPane.add(queryBtn, 2, 0);

        // 初始加载全部机器数据
        System.out.println("请求全部机器数据: " + BASE_URL + "/get");
        HttpRequest allRequest = HttpRequest.newBuilder().uri(URI.create(BASE_URL + "/get")).GET().build();
        httpClient.sendAsync(allRequest, HttpResponse.BodyHandlers.ofString(java.nio.charset.StandardCharsets.UTF_8))
            .thenApply(HttpResponse::body)
            .thenAccept(json -> {
                try {
                    System.out.println("后端返回原始数据: " + json);
                    com.fasterxml.jackson.databind.JsonNode node = objectMapper.readTree(json);
                    com.fasterxml.jackson.databind.JsonNode dataNode = node.get("data");
                    java.util.List<Machine> machines = objectMapper.readValue(dataNode.traverse(), new com.fasterxml.jackson.core.type.TypeReference<java.util.List<Machine>>(){});
                    ObservableList<Machine> data = FXCollections.observableArrayList(machines);
                    javafx.application.Platform.runLater(() -> table.setItems(data));
                } catch (Exception ex) {
                    System.out.println("JSON解析异常: " + ex.getMessage());
                    javafx.application.Platform.runLater(() -> showAlert("初始化数据失败: " + ex.getMessage()));
                }
            })
            .exceptionally(ex -> { javafx.application.Platform.runLater(() -> showAlert("初始化请求失败: " + ex.getMessage())); return null; });

        // 查询按钮事件
        queryBtn.setOnAction(e -> {
            String idText = idField.getText().trim();
            if (idText.isEmpty()) {
                showAlert("请输入要查询的机器ID");
                return;
            }
            System.out.println("请求单个机器，id参数: " + idText);
            String url = BASE_URL + "/get/" + idText;
            HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).GET().build();
            httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString(java.nio.charset.StandardCharsets.UTF_8))
                .thenApply(HttpResponse::body)
                .thenAccept(json -> {
                    try {
                        System.out.println("后端返回原始数据: " + json);
                        com.fasterxml.jackson.databind.JsonNode node = objectMapper.readTree(json);
                        com.fasterxml.jackson.databind.JsonNode dataNode = node.get("data");
                        Machine machine = objectMapper.readValue(dataNode.traverse(), Machine.class);
                        java.util.List<Machine> machines = new java.util.ArrayList<>();
                        if (machine != null) machines.add(machine);
                        ObservableList<Machine> data = FXCollections.observableArrayList(machines);
                        javafx.application.Platform.runLater(() -> table.setItems(data));
                    } catch (Exception ex) {
                        System.out.println("JSON解析异常: " + ex.getMessage());
                        javafx.application.Platform.runLater(() -> showAlert("解析数据失败: " + ex.getMessage()));
                    }
                })
                .exceptionally(ex -> { javafx.application.Platform.runLater(() -> showAlert("请求失败: " + ex.getMessage())); return null; });
        });

        VBox vbox = new VBox(queryPane, table);
        vbox.setPadding(new Insets(10));
        Scene scene = new Scene(vbox, 500, 350);
        dialog.setScene(scene);
        dialog.showAndWait();
    }

    /**
     * 显示错误弹窗
     */
    private void showAlert(String msg) {
        javafx.application.Platform.runLater(() -> new Alert(Alert.AlertType.ERROR, msg).showAndWait());
    }

    /**
     * 显示新增机器的窗口
     */
    public void showAddWindow() {
        Stage stage = new Stage();
        stage.setTitle("新增机器");

        GridPane grid = new GridPane();
        grid.setPadding(new Insets(20));
        grid.setVgap(10);
        grid.setHgap(10);

        grid.add(new Label("机房ID:"), 0, 0);
        ComboBox<Integer> labIdCombo = new ComboBox<>();
        grid.add(labIdCombo, 1, 0);

        grid.add(new Label("机型ID:"), 0, 1);
        ComboBox<Integer> typeIdCombo = new ComboBox<>();
        grid.add(typeIdCombo, 1, 1);

        grid.add(new Label("状态:"), 0, 2);
        ComboBox<String> statusCombo = new ComboBox<>();
        statusCombo.getItems().addAll("available(可用)", "maintenance(维护)", "in use(使用中)");
        statusCombo.setEditable(false);
        grid.add(statusCombo, 1, 2);

        Button submitBtn = new Button("提交");
        submitBtn.setDisable(true);

        // 异步加载机房ID
        HttpRequest labReq = HttpRequest.newBuilder().uri(URI.create("http://localhost:8080/api/lab/get")).GET().build();
        httpClient.sendAsync(labReq, HttpResponse.BodyHandlers.ofString(java.nio.charset.StandardCharsets.UTF_8))
                .thenApply(HttpResponse::body)
                .thenAccept(json -> {
                    try {
                        com.fasterxml.jackson.databind.JsonNode node = objectMapper.readTree(json);
                        com.fasterxml.jackson.databind.JsonNode dataNode = node.get("data");
                        java.util.List<Integer> labIds = new java.util.ArrayList<>();
                        for (com.fasterxml.jackson.databind.JsonNode lab : dataNode) {
                            labIds.add(lab.get("labId").asInt());
                        }
                        javafx.application.Platform.runLater(() -> {
                            labIdCombo.getItems().setAll(labIds);
                            if (!labIds.isEmpty() && !typeIdCombo.getItems().isEmpty()) submitBtn.setDisable(false);
                        });
                    } catch (Exception ex) {
                        javafx.application.Platform.runLater(() -> showAlert("加载机房ID失败: " + ex.getMessage()));
                    }
                });
        // 异步加载机型ID
        HttpRequest typeReq = HttpRequest.newBuilder().uri(URI.create("http://localhost:8080/api/machineType/get")).GET().build();
        httpClient.sendAsync(typeReq, HttpResponse.BodyHandlers.ofString(java.nio.charset.StandardCharsets.UTF_8))
                .thenApply(HttpResponse::body)
                .thenAccept(json -> {
                    try {
                        com.fasterxml.jackson.databind.JsonNode node = objectMapper.readTree(json);
                        com.fasterxml.jackson.databind.JsonNode dataNode = node.get("data");
                        java.util.List<Integer> typeIds = new java.util.ArrayList<>();
                        for (com.fasterxml.jackson.databind.JsonNode type : dataNode) {
                            typeIds.add(type.get("typeId").asInt());
                        }
                        javafx.application.Platform.runLater(() -> {
                            typeIdCombo.getItems().setAll(typeIds);
                            if (!typeIds.isEmpty() && !labIdCombo.getItems().isEmpty()) submitBtn.setDisable(false);
                        });
                    } catch (Exception ex) {
                        javafx.application.Platform.runLater(() -> showAlert("加载机型ID失败: " + ex.getMessage()));
                    }
                });

        submitBtn.setOnAction(e -> {
            Integer labId = labIdCombo.getValue();
            Integer typeId = typeIdCombo.getValue();
            String status = statusCombo.getValue();
            if (labId == null || typeId == null || status == null || status.isEmpty()) {
                showAlert("请填写所有字段");
                return;
            }
            Machine machine = new Machine(0, labId, typeId, status);
            try {
                String json = objectMapper.writeValueAsString(machine);
                System.out.println("[前端] 新增请求内容: " + json);
                HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create(BASE_URL + "/add"))
                        .header("Content-Type", "application/json")
                        .POST(HttpRequest.BodyPublishers.ofString(json, java.nio.charset.StandardCharsets.UTF_8))
                        .build();
                httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString(java.nio.charset.StandardCharsets.UTF_8))
                        .thenApply(HttpResponse::body)
                        .thenAccept(resp -> javafx.application.Platform.runLater(() -> {
                            System.out.println("[前端] 新增响应内容: " + resp);
                            try {
                                com.fasterxml.jackson.databind.JsonNode node = objectMapper.readTree(resp);
                                String code = node.has("code") ? node.get("code").asText() : "";
                                String info = node.has("info") ? node.get("info").asText() : resp;
                                if ("200".equals(code)) {
                                    showInfoDialog("新增成功！");
                                    stage.close();
                                } else {
                                    showInfoDialog("新增失败: " + info);
                                }
                            } catch (Exception ex) {
                                showAlert("响应解析失败: " + ex.getMessage());
                            }
                        }))
                        .exceptionally(ex -> { System.out.println("[前端] 新增异常: " + ex.getMessage()); showAlert("请求失败: " + ex.getMessage()); return null; });
            } catch (Exception ex) {
                System.out.println("[前端] 新增序列化异常: " + ex.getMessage());
                showAlert("序列化失败: " + ex.getMessage());
            }
        });

        grid.add(submitBtn, 1, 3);
        Scene scene = new Scene(grid, 350, 200);
        stage.setScene(scene);
        stage.show();
    }

    /**
     * 显示修改机器的窗口
     */
    public void showUpdateWindow() {
        Stage stage = new Stage();
        stage.setTitle("修改机器");

        GridPane grid = new GridPane();
        grid.setPadding(new Insets(20));
        grid.setVgap(10);
        grid.setHgap(10);

        grid.add(new Label("机器ID:"), 0, 0);
        ComboBox<Integer> idCombo = new ComboBox<>();
        grid.add(idCombo, 1, 0);
        grid.add(new Label("机房ID:"), 0, 1);
        ComboBox<Integer> labIdCombo = new ComboBox<>();
        grid.add(labIdCombo, 1, 1);
        grid.add(new Label("机型ID:"), 0, 2);
        ComboBox<Integer> typeIdCombo = new ComboBox<>();
        grid.add(typeIdCombo, 1, 2);
        grid.add(new Label("状态:"), 0, 3);
        ComboBox<String> statusCombo = new ComboBox<>();
        statusCombo.getItems().addAll("available(可用)", "maintenance(维护)", "in use(使用中)");
        statusCombo.setEditable(false);
        grid.add(statusCombo, 1, 3);

        Button submitBtn = new Button("提交");
        submitBtn.setDisable(true);

        // 异步加载所有机器ID
        HttpRequest allReq = HttpRequest.newBuilder()
                .uri(URI.create("http://localhost:8080/api/machine/get"))
                .GET().build();
        httpClient.sendAsync(allReq, HttpResponse.BodyHandlers.ofString(java.nio.charset.StandardCharsets.UTF_8))
                .thenApply(HttpResponse::body)
                .thenAccept(json -> {
                    try {
                        com.fasterxml.jackson.databind.JsonNode node = objectMapper.readTree(json);
                        com.fasterxml.jackson.databind.JsonNode dataNode = node.get("data");
                        java.util.List<Integer> ids = new java.util.ArrayList<>();
                        for (com.fasterxml.jackson.databind.JsonNode m : dataNode) {
                            ids.add(m.get("machineId").asInt());
                        }
                        javafx.application.Platform.runLater(() -> {
                            idCombo.getItems().setAll(ids);
                            if (!ids.isEmpty() && !labIdCombo.getItems().isEmpty() && !typeIdCombo.getItems().isEmpty()) submitBtn.setDisable(false);
                        });
                    } catch (Exception ex) {
                        javafx.application.Platform.runLater(() -> showAlert("加载机器ID失败: " + ex.getMessage()));
                    }
                });
        // 异步加载机房ID
        HttpRequest labReq = HttpRequest.newBuilder()
                .uri(URI.create("http://localhost:8080/api/lab/get"))
                .GET().build();
        httpClient.sendAsync(labReq, HttpResponse.BodyHandlers.ofString(java.nio.charset.StandardCharsets.UTF_8))
                .thenApply(HttpResponse::body)
                .thenAccept(json -> {
                    try {
                        com.fasterxml.jackson.databind.JsonNode node = objectMapper.readTree(json);
                        com.fasterxml.jackson.databind.JsonNode dataNode = node.get("data");
                        java.util.List<Integer> labIds = new java.util.ArrayList<>();
                        for (com.fasterxml.jackson.databind.JsonNode lab : dataNode) {
                            labIds.add(lab.get("labId").asInt());
                        }
                        javafx.application.Platform.runLater(() -> {
                            labIdCombo.getItems().setAll(labIds);
                            if (!labIds.isEmpty() && !idCombo.getItems().isEmpty() && !typeIdCombo.getItems().isEmpty()) submitBtn.setDisable(false);
                        });
                    } catch (Exception ex) {
                        javafx.application.Platform.runLater(() -> showAlert("加载机房ID失败: " + ex.getMessage()));
                    }
                });
        // 异步加载机型ID
        HttpRequest typeReq = HttpRequest.newBuilder()
                .uri(URI.create("http://localhost:8080/api/machineType/get"))
                .GET().build();
        httpClient.sendAsync(typeReq, HttpResponse.BodyHandlers.ofString(java.nio.charset.StandardCharsets.UTF_8))
                .thenApply(HttpResponse::body)
                .thenAccept(json -> {
                    try {
                        com.fasterxml.jackson.databind.JsonNode node = objectMapper.readTree(json);
                        com.fasterxml.jackson.databind.JsonNode dataNode = node.get("data");
                        java.util.List<Integer> typeIds = new java.util.ArrayList<>();
                        for (com.fasterxml.jackson.databind.JsonNode type : dataNode) {
                            typeIds.add(type.get("typeId").asInt());
                        }
                        javafx.application.Platform.runLater(() -> {
                            typeIdCombo.getItems().setAll(typeIds);
                            if (!typeIds.isEmpty() && !idCombo.getItems().isEmpty() && !labIdCombo.getItems().isEmpty()) submitBtn.setDisable(false);
                        });
                    } catch (Exception ex) {
                        javafx.application.Platform.runLater(() -> showAlert("加载机型ID失败: " + ex.getMessage()));
                    }
                });

        idCombo.setOnAction(e -> {
            Integer selectedId = idCombo.getValue();
            if (selectedId == null) return;
            // 查找已加载的机器数据
            String url = BASE_URL + "/get/" + selectedId;
            HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).GET().build();
            httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString(java.nio.charset.StandardCharsets.UTF_8))
                .thenApply(HttpResponse::body)
                .thenAccept(json -> {
                    try {
                        com.fasterxml.jackson.databind.JsonNode node = objectMapper.readTree(json);
                        com.fasterxml.jackson.databind.JsonNode dataNode = node.get("data");
                        Machine machine = objectMapper.readValue(dataNode.traverse(), Machine.class);
                        if (machine != null) {
                            javafx.application.Platform.runLater(() -> {
                                labIdCombo.setValue(machine.getLabId());
                                typeIdCombo.setValue(machine.getTypeId());
                                statusCombo.setValue(machine.getStatus());
                            });
                        }
                    } catch (Exception ex) {
                        showAlert("加载机器数据失败: " + ex.getMessage());
                    }
                })
                .exceptionally(ex -> { showAlert("请求失败: " + ex.getMessage()); return null; });
        });

        submitBtn.setOnAction(e -> {
            Integer id = idCombo.getValue();
            Integer labId = labIdCombo.getValue();
            Integer typeId = typeIdCombo.getValue();
            String status = statusCombo.getValue();
            if (id == null || labId == null || typeId == null || status == null || status.isEmpty()) {
                showAlert("请填写所有字段");
                return;
            }
            Machine machine = new Machine(id, labId, typeId, status);
            try {
                String json = objectMapper.writeValueAsString(machine);
                System.out.println("[前端] 修改请求内容: " + json);
                HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create(BASE_URL + "/update"))
                        .header("Content-Type", "application/json")
                        .PUT(HttpRequest.BodyPublishers.ofString(json, java.nio.charset.StandardCharsets.UTF_8))
                        .build();
                httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString(java.nio.charset.StandardCharsets.UTF_8))
                        .thenApply(HttpResponse::body)
                        .thenAccept(resp -> javafx.application.Platform.runLater(() -> {
                            System.out.println("[前端] 修改响应内容: " + resp);
                            try {
                                com.fasterxml.jackson.databind.JsonNode node = objectMapper.readTree(resp);
                                String code = node.has("code") ? node.get("code").asText() : "";
                                String info = node.has("info") ? node.get("info").asText() : resp;
                                if ("200".equals(code)) {
                                    showInfoDialog("修改成功！");
                                    stage.close();
                                } else {
                                    showInfoDialog("修改失败: " + info);
                                }
                            } catch (Exception ex) {
                                showAlert("响应解析失败: " + ex.getMessage());
                            }
                        }))
                        .exceptionally(ex -> { System.out.println("[前端] 修改异常: " + ex.getMessage()); showAlert("请求失败: " + ex.getMessage()); return null; });
            } catch (Exception ex) {
                System.out.println("[前端] 修改序列化异常: " + ex.getMessage());
                showAlert("序列化失败: " + ex.getMessage());
            }
        });

        grid.add(submitBtn, 1, 4);
        Scene scene = new Scene(grid, 350, 250);
        stage.setScene(scene);
        stage.show();
    }

    /**
     * 显示删除机器的窗口
     */
    public void showDeleteWindow() {
        Stage stage = new Stage();
        stage.setTitle("删除机器");

        GridPane grid = new GridPane();
        grid.setPadding(new Insets(20));
        grid.setVgap(10);
        grid.setHgap(10);

        grid.add(new Label("机器ID:"), 0, 0);
        ComboBox<Integer> idCombo = new ComboBox<>();
        grid.add(idCombo, 1, 0);

        Button submitBtn = new Button("删除");
        submitBtn.setDisable(true);

        // 异步加载所有可删除的机器ID
        HttpRequest allReq = HttpRequest.newBuilder()
                .uri(URI.create("http://localhost:8080/api/machine/get"))
                .GET().build();
        httpClient.sendAsync(allReq, HttpResponse.BodyHandlers.ofString(java.nio.charset.StandardCharsets.UTF_8))
                .thenApply(HttpResponse::body)
                .thenAccept(json -> {
                    try {
                        com.fasterxml.jackson.databind.JsonNode node = objectMapper.readTree(json);
                        com.fasterxml.jackson.databind.JsonNode dataNode = node.get("data");
                        java.util.List<Integer> ids = new java.util.ArrayList<>();
                        for (com.fasterxml.jackson.databind.JsonNode m : dataNode) {
                            ids.add(m.get("machineId").asInt());
                        }
                        javafx.application.Platform.runLater(() -> {
                            idCombo.getItems().setAll(ids);
                            if (!ids.isEmpty()) submitBtn.setDisable(false);
                        });
                    } catch (Exception ex) {
                        javafx.application.Platform.runLater(() -> showAlert("加载机器ID失败: " + ex.getMessage()));
                    }
                });

        submitBtn.setOnAction(e -> {
            Integer id = idCombo.getValue();
            if (id == null) {
                showAlert("请选择要删除的机器ID");
                return;
            }
            Machine machine = new Machine();
            machine.setMachineId(id);
            try {
                String json = objectMapper.writeValueAsString(machine);
                System.out.println("[前端] 删除请求内容: " + json);
                HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create(BASE_URL + "/delete"))
                        .header("Content-Type", "application/json")
                        .method("DELETE", HttpRequest.BodyPublishers.ofString(json, java.nio.charset.StandardCharsets.UTF_8))
                        .build();
                httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString(java.nio.charset.StandardCharsets.UTF_8))
                        .thenApply(HttpResponse::body)
                        .thenAccept(resp -> javafx.application.Platform.runLater(() -> {
                            System.out.println("[前端] 删除响应内容: " + resp);
                            try {
                                com.fasterxml.jackson.databind.JsonNode node = objectMapper.readTree(resp);
                                String code = node.has("code") ? node.get("code").asText() : "";
                                String info = node.has("info") ? node.get("info").asText() : resp;
                                if ("200".equals(code)) {
                                    showInfoDialog("删除成功！");
                                    stage.close();
                                } else {
                                    showInfoDialog("删除失败: " + info);
                                }
                            } catch (Exception ex) {
                                showAlert("响应解析失败: " + ex.getMessage());
                            }
                        }))
                        .exceptionally(ex -> { System.out.println("[前端] 删除异常: " + ex.getMessage()); showAlert("请求失败: " + ex.getMessage()); return null; });
            } catch (Exception ex) {
                System.out.println("[前端] 删除序列化异常: " + ex.getMessage());
                showAlert("序列化失败: " + ex.getMessage());
            }
        });

        grid.add(submitBtn, 1, 1);
        Scene scene = new Scene(grid, 350, 150);
        stage.setScene(scene);
        stage.show();
    }

    /**
     * 显示标准信息弹窗
     * @param msg 提示信息
     */
    private void showInfoDialog(String msg) {
        javafx.application.Platform.runLater(() -> {
            Alert alert = new Alert(Alert.AlertType.INFORMATION);
            alert.setTitle("消息");
            alert.setHeaderText(null);
            alert.setContentText(msg);
            alert.showAndWait();
        });
    }
} 